<?php
namespace App\Services;

use App\Helpers\Api\PayTrait;
use App\Helpers\Api\TtMiniTrait;
use App\Models\MallOrder;
use App\Models\MallOrderProduct;
use App\Models\MallProductStock;
use App\Models\MallRefund;
use App\Models\Order;
use App\Models\Product;

class MallRefundService {
    use PayTrait, TtMiniTrait;

    public static function handle($input, $action, $is_transaction = true) {

        try {
            $is_transaction && \DB::beginTransaction();
            $orderProduct = MallOrderProduct::lockForUpdate()->find($input['order_product_id']);
            if (!$orderProduct)
                throw new \Exception('货品不存在');

            $refund = MallRefund::find($input['refund_id']);
            if (!$refund)
                throw new \Exception('不存在退款单号');

            $is_paid = false;
            if ($action == 'agree') {
                if (!in_array($refund->status, [MallRefund::STATUS_WAIT_REFUND, MallRefund::STATUS_DELIVER_PRODUCT]))
                    throw new \Exception('当前订单状态不允许同意退款');

                if ($refund->is_return_product) {
                    if ($refund->audit_start_at) {
                        //打款
                        $refund->status = MallRefund::STATUS_REFUND_ING;
                        $refund->product_end_at = date('Y-m-d H:i:s');
                        $is_paid = true;

                    } else {
                        //退货
                        $refund->status = MallRefund::STATUS_DELIVER_PRODUCT;
                        $refund->audit_start_at = date('Y-m-d H:i:s');
                    }
                } else {
                    $is_paid = true;
                    $refund->status = MallRefund::STATUS_REFUND_ING;
                    $refund->audit_start_at = date('Y-m-d H:i:s');
                }
                $refund->save();

                if ($is_paid) {
                    //库存
                    MallProductStock::where('product_id', $orderProduct->product_id)->where('key', $orderProduct->specs_str)->increment('stock', $orderProduct->buy_num);
                    MallProductStock::flushQueryCache();
                    $product_model = Product::find($orderProduct->product_id);
                    if ($product_model) {
                        $product_model->stock = $product_model->stock + $orderProduct->buy_num;
                        $product_model->save();
                    }
                }

                //打款
                $self = new self();
                if ($is_paid) {
                    if ($refund->pay_type == 1) {
                        $obj  = $self->payApp();
                        $config = [
                            'out_request_no' => $refund->refund_sn,
                            'out_trade_no' => $orderProduct->pay_order_sn,
                            'refund_amount' => format_yuan($refund->paid_amount)
                        ];
                        $response = $obj->refund($config);
                        $refund->out_trade_no = $response->trade_no;
                    } else {
                        $obj  = $self->payWx();
                        $mall_order = MallOrder::find($orderProduct->order_id);
                        $total_fee= MallOrder::where('pay_order_sn', $mall_order->pay_order_sn)->sum('paid_amount');
                        $config = [
                            'out_trade_no' => $orderProduct->pay_order_sn,
                            'out_refund_no' => $refund->refund_sn,
                            'total_fee' => $total_fee,
                            'refund_fee' => $refund->paid_amount,
                            'notify_url' => route('wx.refund.notify')
                        ];
                        \Log::info(var_export($config, true));
                        $response = $obj->refund($config);
                        $refund->out_trade_no = $response->transaction_id;
                    }
                    $refund->paid_end_at = date('Y-m-d H:i:s');
                    $refund->status = MallRefund::STATUS_REFUND_SUCCESS;
                }
                $refund->save();
                
            } else if($action == 'refuse') {
                if ($refund->status !=  MallRefund::STATUS_WAIT_REFUND)
                    throw new \Exception('当前状态无法操作拒绝退款');

                $refund->status = MallRefund::STATUS_REFUSE;
                if ($refund->audit_start_at) {
                    //货品拒绝
                    $refund->product_end_at = date('Y-m-d H:i:s');
                } else {
                    $refund->audit_start_at = date('Y-m-d H:i:s');
                }
                $refund->save();

                //是否存在其他正在退货中
                $exist_other_refunding = MallOrderProduct::where('order_id', $orderProduct->order_id)->where('id', '!=', $orderProduct->id)->where('is_zero', 0)
                    ->whereIn('refund_status', [1, 2, 3])->exists();
                if (!$exist_other_refunding) {
                    $order = MallOrder::find($orderProduct->order_id);
                    if ($order->status == MallOrder::STATUS_DELIVER_PRODUCT) {
                        $order->express_end_at = date('Y-m-d H:i:s', strtotime("+10 day"));
                        $order->save();
                    }
                }

            } else if ($action == 'cancel') {
                if ($refund->status !=  MallRefund::STATUS_WAIT_REFUND)
                    throw new \Exception('当前状态无法取消退款');

                $refund->status = MallRefund::STATUS_CANCEL;
                $refund->save();

                //是否存在其他正在退货中
                $exist_other_refunding = MallOrderProduct::where('order_id', $orderProduct->order_id)->where('id', '!=', $orderProduct->id)->where('is_zero', 0)
                    ->whereIn('refund_status', [1, 2, 3])->exists();

                if (!$exist_other_refunding) {
                    $order = MallOrder::find($orderProduct->order_id);
                    if ($order->status == MallOrder::STATUS_DELIVER_PRODUCT) {
                        $order->express_end_at = date('Y-m-d H:i:s', strtotime("+10 day"));
                        $order->save();
                    }
                }

            }

            $orderProduct->refund_status = $refund->status;
            $orderProduct->save();

            if ($action == 'agree' && $is_paid) {
                $orderProduct->status = MallOrderProduct::STATUS_REFUND_FINISH;
                $orderProduct->save();
                //判断是否所有都未退款
                $exists = MallOrderProduct::where('order_id', $orderProduct->order_id)->where('is_zero', 0)->where('status', '!=', MallOrderProduct::STATUS_REFUND_FINISH)->exists();
                if (!$exists) {
                    $mall_order = MallOrder::find($orderProduct->order_id);
                    $mall_order->status = MallOrder::STATUS_CLOSE;
                    $mall_order->save();
                }

                //是否存在其他正在退货中
                $exist_other_refunding = MallOrderProduct::where('order_id', $orderProduct->order_id)->where('id', '!=', $orderProduct->id)->where('is_zero', 0)
                    ->whereIn('refund_status', [1, 2, 3])->exists();
                if (!$exist_other_refunding) {
                    $order = MallOrder::find($orderProduct->order_id);
                    if ($order->status == MallOrder::STATUS_DELIVER_PRODUCT) {
                        $order->express_end_at = date('Y-m-d H:i:s', strtotime("+10 day"));
                        $order->save();
                    }
                }
            }
            \DB::commit();
        } catch (\Exception $e) {
            \Log::error($e);
            $is_transaction && \DB::rollBack();
            throw new \Exception($e->getMessage());
        }
    }

}
